#ifndef WEATHERDATAFETCHER_H
#define WEATHERDATAFETCHER_H

#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>
#include <QStringList>
#include <QVariant>

class WeatherDataFetcher : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString cityName READ cityName NOTIFY cityNameChanged)
    Q_PROPERTY(QString temperature READ temperature NOTIFY temperatureChanged)
    Q_PROPERTY(QString weatherCondition READ weatherCondition NOTIFY weatherConditionChanged)
    Q_PROPERTY(QString humidity READ humidity NOTIFY humidityChanged)
    Q_PROPERTY(QString windSpeed READ windSpeed NOTIFY windSpeedChanged)
    Q_PROPERTY(QString pressure READ pressure NOTIFY pressureChanged)
    Q_PROPERTY(QString visibility READ visibility NOTIFY visibilityChanged)
    Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
    // 接口盒子（cn.apihz.cn）凭证
    Q_PROPERTY(QString apiHzId READ apiHzId WRITE setApiHzId NOTIFY apiHzIdChanged)
    Q_PROPERTY(QString apiHzKey READ apiHzKey WRITE setApiHzKey NOTIFY apiHzKeyChanged)
    // APIHZ 扩展字段
    Q_PROPERTY(QVariantList hourly READ hourly NOTIFY hourlyChanged)
    Q_PROPERTY(QString icon READ icon NOTIFY iconChanged)
    Q_PROPERTY(QString feelsLike READ feelsLike NOTIFY feelsLikeChanged)
    Q_PROPERTY(QString windDirection READ windDirection NOTIFY windDirectionChanged)
    Q_PROPERTY(QString windScale READ windScale NOTIFY windScaleChanged)
    Q_PROPERTY(QString precipitation READ precipitation NOTIFY precipitationChanged)
    Q_PROPERTY(QString updateTime READ updateTime NOTIFY updateTimeChanged)

public:
    explicit WeatherDataFetcher(QObject *parent = nullptr);

    QString cityName() const { return m_cityName; }
    QString temperature() const { return m_temperature; }
    QString weatherCondition() const { return m_weatherCondition; }
    QString humidity() const { return m_humidity; }
    QString windSpeed() const { return m_windSpeed; }
    QString pressure() const { return m_pressure; }
    QString visibility() const { return m_visibility; }
    bool loading() const { return m_loading; }
    QString apiHzId() const { return m_apiHzId; }
    QString apiHzKey() const { return m_apiHzKey; }
    QVariantList hourly() const { return m_hourly; }
    QString icon() const { return m_icon; }
    QString feelsLike() const { return m_feelsLike; }
    QString windDirection() const { return m_windDirection; }
    QString windScale() const { return m_windScale; }
    QString precipitation() const { return m_precipitation; }
    QString updateTime() const { return m_updateTime; }

    Q_INVOKABLE void fetchWeather(const QString &city);
    Q_INVOKABLE void fetchWeatherByLocation(double latitude, double longitude);
    Q_INVOKABLE void setApiHzId(const QString &id) { if (m_apiHzId != id) { m_apiHzId = id; emit apiHzIdChanged(); } }
    Q_INVOKABLE void setApiHzKey(const QString &key) { if (m_apiHzKey != key) { m_apiHzKey = key; emit apiHzKeyChanged(); } }

signals:
    void cityNameChanged();
    void temperatureChanged();
    void weatherConditionChanged();
    void humidityChanged();
    void windSpeedChanged();
    void pressureChanged();
    void visibilityChanged();
    void loadingChanged();
    void weatherFetched(bool success, const QString &error = "");
    void apiHzIdChanged();
    void apiHzKeyChanged();
    void hourlyChanged();
    void iconChanged();
    void feelsLikeChanged();
    void windDirectionChanged();
    void windScaleChanged();
    void precipitationChanged();
    void updateTimeChanged();

private slots:
    void onNetworkReplyFinished(QNetworkReply *reply);

private:
    void parseWeatherData(const QJsonObject &json);
    void parseApiHzWeather(const QJsonObject &json);
    void prepareApiHzCandidates();
    QString buildApiHzUrl(const QString &base, const QString &sheng, const QString &place) const;
    void issueApiHzRequest();
    void setCityName(const QString &name);
    void setTemperature(const QString &temp);
    void setWeatherCondition(const QString &condition);
    void setHumidity(const QString &hum);
    void setWindSpeed(const QString &wind);
    void setPressure(const QString &pres);
    void setVisibility(const QString &vis);
    void setLoading(bool load);
    void setHourly(const QVariantList &list) { m_hourly = list; emit hourlyChanged(); }
    void setIcon(const QString &i) { if (m_icon != i) { m_icon = i; emit iconChanged(); } }
    void setFeelsLike(const QString &v) { if (m_feelsLike != v) { m_feelsLike = v; emit feelsLikeChanged(); } }
    void setWindDirectionStr(const QString &v) { if (m_windDirection != v) { m_windDirection = v; emit windDirectionChanged(); } }
    void setWindScaleStr(const QString &v) { if (m_windScale != v) { m_windScale = v; emit windScaleChanged(); } }
    void setPrecipitation(const QString &v) { if (m_precipitation != v) { m_precipitation = v; emit precipitationChanged(); } }
    void setUpdateTime(const QString &v) { if (m_updateTime != v) { m_updateTime = v; emit updateTimeChanged(); } }

    QNetworkAccessManager *m_networkManager;
    QString m_cityName;
    QString m_temperature;
    QString m_weatherCondition;
    QString m_humidity;
    QString m_windSpeed;
    QString m_pressure;
    QString m_visibility;
    bool m_loading;
    QString m_apiHzId;
    QString m_apiHzKey;
    // APIHZ 重试用的候选基础地址与状态
    QStringList m_apiHzBases;
    int m_apiHzTryIndex { 0 };
    QString m_lastShengParam;
    QString m_lastPlaceParam;
    // 扩展数据
    QVariantList m_hourly;
    QString m_icon;
    QString m_feelsLike;
    QString m_windDirection;
    QString m_windScale;
    QString m_precipitation;
    QString m_updateTime;
};

#endif // WEATHERDATAFETCHER_H

